package com.example.project.projectspringcloud.utils;

import com.example.project.projectspringcloud.common.Constants;
import com.example.project.projectspringcloud.entity.sys.SysConfig;
import com.example.project.projectspringcloud.entity.video.Video;
import com.google.gson.Gson;
import sun.misc.BASE64Encoder;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class TencentVideoUtil {

    /**
     * 获取前台视频加载所需参数
     * @param video 视频文件
     * @param sysConfigs tencentcloud sys list
     * @param experFlag 是否需要试看
     * @param refresh 强制刷新, 重新从腾讯拉取
     * @return
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     */
    public static Video getTCPlayParam(Video video, boolean experFlag, List<SysConfig> sysConfigs, RedisUtil redisUtil, boolean refresh) throws Exception {
        if(!refresh && redisUtil.hasKey(Constants.VIDEO_CACHE_PREFIX + video.getId())) {
            Video temp = new Gson().fromJson((String) redisUtil.get(Constants.VIDEO_CACHE_PREFIX + video.getId()), Video.class);
            video.setT(temp.getT());
            video.setSign(temp.getSign());
            video.setAppId(temp.getAppId());
            video.setKEY(temp.getKEY());
            video.setSecretKey(temp.getSecretKey());
            video.setSecretId(temp.getSecretId());
            video.setExper(temp.getExper());
            return video;
        }
        // 加载配置
        SortedMap tencentcloud = new TreeMap();
        Video configVideo = new Video();
        sysConfigs.forEach(t -> {
            tencentcloud.put(t.getColumn(), t.getValue());
        });

        video.setSecretId((String) tencentcloud.get("secretId"));
        video.setSecretKey((String) tencentcloud.get("secretKey"));
        // 防盗链KEY
        video.setKEY((String) tencentcloud.get("KEY"));
        video.setAppId((String) tencentcloud.get("appId"));
        // 试看时长
        video.setExper(Integer.valueOf(tencentcloud.get("exper").toString()));

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, 1);
        long t = calendar.getTimeInMillis() / 1000L;

        // 获取视频信息
        String resultJson = "";
        try {
            resultJson = getVideoInfo(video.getUrl(), video.getSecretId(), video.getSecretKey());
        } catch (Exception e) {
            try {
                resultJson = getVideoInfo(video.getUrl(), video.getSecretId(), video.getSecretKey());
            } catch (Exception e1) {
                throw new Exception("视频加载失败!");
            }
        }
        Map videoInfoMap = JsonUtil.json2Map(resultJson);
        if ((Integer) videoInfoMap.get("code") == 0) {
            Map basicInfo = (Map) videoInfoMap.get("basicInfo");
            String dir = ((String) basicInfo.get("sourceVideoUrl")).split(".com")[1];
            dir = dir.substring(0, dir.lastIndexOf("/") + 1);
            // 生成MD5签名, 判断是否需要试看时间
            if(experFlag) {
                String sign = StringUtil.md5(video.getKEY() + video.getAppId() + video.getUrl() + Integer.toHexString((int) t) + video.getExper());
                video.setSign(sign);
            } else {
                String sign = StringUtil.md5(video.getKEY() + video.getAppId() + video.getUrl() + Integer.toHexString((int) t));
                video.setSign(sign);
            }
            video.setT(Integer.toHexString((int) t));
        }
        redisUtil.set(Constants.VIDEO_CACHE_PREFIX + video.getId(), new Gson().toJson(video), 82800);
        return video;
    }

    /**
     * getVideoInfo
     *
     * @param fileId    视频文件ID
     * @param secretId  secretId
     * @param secretKey secretKey
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public static String getVideoInfo(String fileId, String secretId, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        long now = calendar.getTimeInMillis() / 1000L;
        calendar.add(Calendar.MINUTE, 5);
        long t = calendar.getTimeInMillis() / 1000L;

        // 获取视频信息
        SortedMap param = new TreeMap();
        param.put("Action", "GetVideoInfo");
        param.put("Nonce", String.valueOf(t));
        param.put("fileId", fileId);
        param.put("SecretId", secretId);
        param.put("Region", "bj");
        param.put("Timestamp", String.valueOf(now));
        param.put("SignatureMethod", "HmacSHA256");
        StringBuffer sb = new StringBuffer("POSTvod.api.qcloud.com/v2/index.php?");
        param.forEach((k, v) -> {
            sb.append(k + "=" + v + "&");
        });
        sb.setLength(sb.length() - 1);

        Mac sha256HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
        sha256HMAC.init(secretKeySpec);
        String hash = new BASE64Encoder().encode(sha256HMAC.doFinal(sb.toString().getBytes()));

        param.put("Signature", hash);
        return HttpUtil.post("https://vod.api.qcloud.com/v2/index.php", param);
    }
}
